package org.afox.parsers.xml;

import java.util.*;

import org.xml.sax.*;
import org.xml.sax.helpers.*;

/** This class provides a Base handler for parsing XML data.  It is used in addition to
the SAX parsing system.  This class adds reflection to ease parsing of XML data.
*/

public class BaseHandler extends DefaultHandler
{
	private LinkedList handlerStack = new LinkedList();
	private String basePackage;
	public Object result;

	public BaseHandler(String aBasePackage)
	{
		if (aBasePackage == null)
			throw new IllegalArgumentException("Base Package cannot be null");
		basePackage = aBasePackage;

		if (!basePackage.endsWith("."))
			basePackage = basePackage + ".";
	}

	public Object getResult()
	{
		return result;
	}

	public void setResult(Object aResult)
	{
		result = aResult;
	}

	public ReflectiveHandler pushNewHandler(String qualifiedName) throws SAXException 
	{
		try
		{
			handlerStack.addLast(Class.forName(basePackage + 
						       "xml." + 
						       qualifiedName + 
						       "Handler").newInstance());
			((ReflectiveHandler)getCurrentHandler()).setMainHandler(this);
			((ReflectiveHandler)getCurrentHandler()).setName(qualifiedName);
		}
		catch (Exception x)
		{
			//			System.out.println("Cannot find handler:" + qualifiedName);
			throw new SAXException("Cannot find content handler for tag: " + qualifiedName);
		}
		return getCurrentHandler();
	}

	public ReflectiveHandler popHandler()
	{
		return (ReflectiveHandler)handlerStack.removeLast();
	}

	public ReflectiveHandler getCurrentHandler()
	{
		return (ReflectiveHandler)handlerStack.getLast();
	}

	public ReflectiveHandler getParentHandler(ReflectiveHandler aHandler) throws SAXException
	{
		try
		{
			int index = handlerStack.indexOf(aHandler);
			return (ReflectiveHandler) handlerStack.get(index-1);
		}
		catch (Exception x)
		{
			throw new SAXException("Cannot find parent handler: ");
		}
	}

	public void startElement(String namespace, String localName, String qualifiedName, Attributes attrs) 
                throws SAXException
        {
		if (handlerStack.size() == 0)
			pushNewHandler(qualifiedName);

		getCurrentHandler().startElement(namespace, localName, qualifiedName, attrs);
	}

	public void endElement(String namespace, String localName, String qualifiedName)
                throws SAXException
        {
		try
		{
			getCurrentHandler().endElement(namespace, localName, qualifiedName);
		}
		catch (Exception x)
		{
			throw new SAXException("Cannot find content handler for tag: " + qualifiedName);
		}
	}

	public void characters(char[] ch, int start, int end) throws SAXException
        {
		try
		{
			getCurrentHandler().characters(ch, start, end);
		}
		catch (Exception x)
		{
			throw new SAXException("Cannot find current content handler.");
		}
        }

}
